package microphone;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

/**
 *
 * @author Tom Pepels
 */
public class ClientThread extends Thread {

    private int serverPort;
    private boolean running = true;
    private Collection<InetAddress> destinations;
    private MicrophoneThread microphone;
    private short callerId;
    private DatagramSocket socket = null;

    public ClientThread(int serverPort, MicrophoneThread microphone, short callerId) {
        destinations = new ArrayList<InetAddress>();
        destinations = Collections.synchronizedCollection(destinations);
        this.serverPort = serverPort;
        this.microphone = microphone;
        this.callerId = callerId;
    }

    @Override
    public void run() {
        running = true;
        while (running) {
            try {
                float[] data = microphone.signalQueue.take();
                short[] sData = AudioProcessing.forward(data);
                short head = 0, tail = 0;

                for (int i = 0; i < sData.length; i++) {
                    if (sData[i] != 0) {
                        break;
                    }
                    head++;
                }
                if (head >= sData.length) {
                    continue; // Data is empty
                }
                short j = (short) (sData.length - 1);
                for(int i = j; i > 0; i--) {
                    if(sData[i] != 0) {
                        break;
                    }
                    tail++;
                }
                
                byte[] buffer = new byte[((j - head) * 2) + 18];
                ByteBuffer bb = ByteBuffer.wrap(buffer);

                // Header data,
                // Caller id
                bb.putShort(callerId);
                // The amount of heading zeroes
                bb.putShort(head);
                // The amount of tailing zeroes
                bb.putShort(tail);
                // Spacer of int_size zeroes
                bb.putInt(0);

                // Le data
                for (int i = head; i < j; i++) {
                    bb.putShort(sData[i]);
                }
                // Spacer of int_size zeroes
                bb.putInt(0);

                DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
                dp.setPort(serverPort);
                try {
                    socket = new DatagramSocket();

                    for (InetAddress a : destinations) {
                        dp.setAddress(a);
                        socket.send(dp);
                    }
                } catch (IOException ex) {
                    System.err.println(ex);
                }
            } catch (InterruptedException ex) {
                System.err.println(ex);
            }
        }
    }

    public void stopRunning() {
        running = false;
    }

    public void addAddress(InetAddress address) {
        destinations.add(address);
    }
}
